#include "libServoShm.h"
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define ServoShmKey  1000
int  ServoShm_ID=-1;
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
/**
 * 创建共享内存
 * */
int Init_ServoShm(void){
    int shmid = shmget((key_t)ServoShmKey,sizeof(ServoShm), 0666|IPC_CREAT);
    if(shmid == -1)
    {
        perror("shmget");
        return -1;
    }
    ServoShm_ID = shmid;
    return 0;
}
/**
 *获取共享内存指针
 * 正常返回共享内存的地址，失败返回NULL
 * */
void *Get_Shm_Pointer(void){
    if(ServoShm_ID==-1){
        printf("[ERROR]ServoShm is not Init\n");
        return NULL;
    }
    void * p=NULL;
    p = shmat(ServoShm_ID, NULL, 0);
    if ( p == (void *) -1) {
        perror("shmat");
        return NULL;
    }
    return p;
}
/**
 * 读取数据
 *@param p 共享内存的地址
 *@param num 数据序号
 *@param data 返回数据
 *@param flag 数据对应的flag
 *
 *@return -1 获取失败 0 获取成功
 * */
int Read_Data_pram(void * p,int num,int *data,int *flag){
    if(p==NULL)
    {
        printf("[ERROR] Pointer is NULL\n");
        return -1;
    }
    if(num>ServoShm_Num_pram){
        printf("[ERROR] num is so big\n");
        return -1;
    }
    ServoShm *pdata = (ServoShm *) p;
    *data = pdata->pram[num].value;
    *flag = pdata->pram[num].value_flag;
    return 0;
}
/**
 * 读取数据
 *@param p 共享内存的地址
 *@param num 数据序号
 *@param data 写入数据
 *@param flag 数据对应的flag 1有效 0视为无效 不写入
 *
 *@return -1 获取失败 0 获取成功
 * */
int Set_Data_pram(void * p,int num,int data,int flag){
    if(p==NULL)
    {
        printf("[ERROR] Pointer is NULL\n");
        return -1;
    }
    if(num>ServoShm_Num_pram){
        printf("[ERROR] num is to long\n");
        return -1;

    }

    ServoShm *pdata = (ServoShm *) p;
    pthread_rwlock_wrlock(&rwlock);
    pdata->pram[num].value_flag = flag; //写操作时 先将falg 置1 防止其它的重复写
    pdata->pram[num].value  = data ;
    pthread_rwlock_unlock(&rwlock);
    return 0;
}
